﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Epsilon.Expr;

namespace Epsilon.Parse
{
    public partial class Parser
    {
        public IPattern ParsePattern()
        {
            if (CheckType(TokenType.Variable))
            {
                Token t = CurrentToken();
                Chomp();
                return new VarExpr(t.Value, t.Line, t.Col);
            }
            else if (MatchPeek(TokenType.Symbol, "{"))
            {
                Token t = CurrentToken();
                Chomp();
                List<IPattern> patterns = ParsePatterns();
                Match(TokenType.Symbol, "}");
                return new PatternTuple(patterns, t.Line, t.Col);
            }
            else if (MatchPeek(TokenType.Symbol, "#"))
            {
                Token t = CurrentToken();
                Chomp();
                if (CheckType(TokenType.Atom))
                {
                    string name = CurrentToken().Value;
                    Chomp();
                    Match(TokenType.Symbol, "{");
                    List<PatternRecField> fields = ParsePatternRecFields();
                    Match(TokenType.Symbol, "}");
                    return new PatternRec(name, fields, t.Line, t.Col);
                }
                else
                {
                    Error("Expected a record name");
                }
            }
            return null;
        }

        public PatternRecField ParsePatternRecField()
        {
            if (CheckType(TokenType.Atom))
            {
                Token t = CurrentToken();
                Chomp();
                Match(TokenType.Symbol, "=");
                IPattern pattern = ParsePattern();
                return new PatternRecField(t.Value, pattern, t.Line, t.Col);
            }
            else
            {
                Error("Expected a record field name");
            }
            return null;
        }

        public List<IPattern> ParsePatterns()
        {
            List<IPattern> patterns = new List<IPattern>();
            patterns.Add(ParsePattern());
            while (MatchPeek(TokenType.Symbol, ","))
            {
                Chomp();
                patterns.Add(ParsePattern());
            }
            return patterns;
        }

        public List<PatternRecField> ParsePatternRecFields()
        {
            List<PatternRecField> fields = new List<PatternRecField>();
            fields.Add(ParsePatternRecField());
            while (MatchPeek(TokenType.Symbol, ","))
            {
                Chomp();
                fields.Add(ParsePatternRecField());
            }
            return fields;
        }
    }
}
